package org.shagin.jfin.date.cond;

import static org.shagin.jfin.date.DateUtils.isEqual;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

import org.shagin.jfin.date.DateUtils;

/**
 * The Class DateCondition.
 */
@SuppressWarnings("serial")
public abstract class DateCondition implements IDateCondition {

    protected DateRange range = new DateRange();
    protected Calendar cal = Calendar.getInstance();

    /**
     * Instantiates a new date condition.
     */
    public DateCondition() {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean validDate(Date date) {
        return range.contain(date);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public DateRange getRange() {
        return range;
    }

    /**
     * {@inheritDoc}
     */
    public String toString() {
        return getClass().getSimpleName() + " " + toString(range);
    }

    /**
     * To string.
     * 
     * @param range the range
     * @return the string
     */
    public static String toString(DateRange range) {
        StringBuilder sb = new StringBuilder();
        if (!isEqual(range.getStart(), DateUtils.CLOSE_DATE))
            sb.append(" с ").append(DateUtils.format(range.getStart()));
        if (!isEqual(range.getEnd(), DateUtils.OPEN_DATE))
            sb.append(" по ").append(DateUtils.format(range.getEnd()));
        return sb.toString().trim();
    }

    /**
     * Array2 string.
     * 
     * @param <T> the generic type
     * @param a the a
     * @return the string
     */
    public static String join(int[] a) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < a.length; i++) {
            sb.append(a[i] + "");
            sb.append(i < a.length - 1 ? "," : "");
        }
        return sb.toString();

    }
    /**
     * To string ordered.
     * 
     * @param a the a
     * @return the string
     */
    public static String toStringOrdered(int[] a) {
        Arrays.sort(a);
        StringBuilder sb = new StringBuilder();

        if (a.length > 0) {

            int l = a[0];
            int p = l;
            sb.append(p);
            boolean isLast = false;
            boolean isDelimeter = false;
            boolean isZ = false;
            boolean isOrd = false;
            boolean isOrdL = false;
            for (int i = 1; i < a.length; i++) {
                int c = a[i];
                isLast = !(i < a.length - 1);
                isOrd = (c - p == 1);
                isOrdL = (c - l == 1);
                if (i == 1) {
                    if (a.length == 2) {
                        sb.append(",").append(c);
                        return sb.toString();
                    } else if (a.length >= 3) {
                        int a2 = a[2];
                        if ((a2 - c == 1) && (c - a[0] == 1)) {
                            sb.append("-");
                            isZ = false;
                            isDelimeter = true;
                        } else {
                            sb.append(",");
                            isZ = true;
                            isDelimeter = false;
                        }
                    }
                }

                if (isOrd) {
                    if (isZ) {
                        sb.append(c);
                        l = c;
                        p = c;
                        isZ = false;
                        isDelimeter = false;
                    } else {
                        if (isOrdL) {
                            if (isDelimeter) {
                            } else {
                                sb.append("-");
                                isZ = false;
                                isDelimeter = true;
                            }
                        } else {
                            if (isDelimeter) {
                            } else {
                                sb.append("-");
                                isZ = false;
                                isDelimeter = true;
                            }
                        }
                    }
                } else {
                    if (isZ) {
                        sb.append(c);
                    } else {
                        if (isDelimeter) {
                            if (!isOrdL) {
                                sb.append(p).append(",").append(c);
                            }
                        } else {
                            sb.append(",").append(c);
                        }
                    }
                    l = c;
                    p = c;
                    isZ = false;
                    isDelimeter = false;
                }

                if (isLast) {
                    if (c != l) {
                        if (!isDelimeter)
                            sb.append("-");
                        sb.append(c);
                    }
                }
                p = c;
            }
        }
        return sb.toString();
    }

    /**
     * The main method.
     * 
     * @param args the arguments
     */
    public static void main(String[] args) {
        System.out.println(DateCondition.toStringOrdered(new int[]{1, 2, 3, 4,
                5, 6, 7, 8, 9}));
        System.out.println(DateCondition.toStringOrdered(new int[]{1, 3, 4, 5,
                6, 7}));
        System.out.println(DateCondition.toStringOrdered(new int[]{1, 2, 3, 5,
                7, 9}));
        System.out.println(DateCondition.toStringOrdered(new int[]{1, 2, 4}));
        System.out.println(DateCondition.toStringOrdered(new int[]{1, 3, 4, 6,
                7}));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String format() {
        return this.getClass().getSimpleName();
    }
}
